import java.net.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class CustomNTPServer {
    private static final int NTP_PORT = 123;
    private static final long NTP_EPOCH_OFFSET = 2208988800L; // 1900到1970的秒数偏移

    private JFrame frame;
    private JCheckBox syncCheckbox;
    private JTextField timeField;
    private JButton startButton;
    private JLabel statusLabel;

    public CustomNTPServer() {
        frame = new JFrame("NTP 服务器设置");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5);

        // 复选框：启动服务器
        syncCheckbox = new JCheckBox("启动 NTP 服务器");
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.anchor = GridBagConstraints.WEST;
        frame.add(syncCheckbox, gbc);

        // 时间输入标签和文本框
        JLabel timeLabel = new JLabel("设置时间(yyyy-MM-dd HH:mm:ss):");
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.anchor = GridBagConstraints.EAST;
        frame.add(timeLabel, gbc);
        timeField = new JTextField(20);
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.anchor = GridBagConstraints.WEST;
        frame.add(timeField, gbc);

        // 启动按钮
        startButton = new JButton("启动");
        gbc.gridx = 2;
        gbc.gridy = 1;
        frame.add(startButton, gbc);

        // 状态标签
        statusLabel = new JLabel("状态: 未启动");
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.gridwidth = 3;
        frame.add(statusLabel, gbc);

        frame.pack();
        frame.setLocationRelativeTo(null);

        // 启动按钮点击事件
        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (syncCheckbox.isSelected()) {
                    String timeStr = timeField.getText();
                    if (timeStr.isEmpty()) {
                        JOptionPane.showMessageDialog(frame, "请输入时间");
                        return;
                    }
                    try {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
                        Date targetDate = sdf.parse(timeStr);
                        long targetTime = (targetDate.getTime() / 1000) + NTP_EPOCH_OFFSET;

                        statusLabel.setText("状态: 启动中...");
                        new Thread(() -> runServer(targetTime)).start(); // 后台线程运行服务器
                    } catch (Exception ex) {
                        statusLabel.setText("状态: 时间格式错误");
                        ex.printStackTrace();
                    }
                } else {
                    statusLabel.setText("状态: 未启动");
                }
            }
        });
    }

    // 运行NTP服务器
    private void runServer(long targetTime) {
        try (DatagramSocket socket = new DatagramSocket(NTP_PORT)) {
            statusLabel.setText("状态: 服务器运行中，监听端口 " + NTP_PORT);
            byte[] buffer = new byte[48];
            DatagramPacket request = new DatagramPacket(buffer, buffer.length);

            while (true) {
                socket.receive(request);
                InetAddress clientAddress = request.getAddress();
                int clientPort = request.getPort();

                byte[] responseData = buildNtpResponse(targetTime);
                DatagramPacket response = new DatagramPacket(
                        responseData, responseData.length, clientAddress, clientPort
                );
                socket.send(response);
                statusLabel.setText("状态: 已发送响应到 " + clientAddress.getHostAddress());
            }
        } catch (Exception ex) {
            statusLabel.setText("状态: 服务器错误 - " + ex.getMessage());
            ex.printStackTrace();
        }
    }

    // 构建NTP响应包
    private static byte[] buildNtpResponse(long targetTime) {
        ByteBuffer buffer = ByteBuffer.allocate(48);
        buffer.order(ByteOrder.BIG_ENDIAN);

        buffer.put((byte) 0x23); // LI=0, VN=3, Mode=4 (服务器模式)
        buffer.put((byte) 1);     // Stratum=1 (主服务器)
        buffer.put((byte) 0);    // Poll Interval
        buffer.put((byte) 0xFA); // 精度

        buffer.putInt(0); // Root Delay
        buffer.putInt(0); // Root Dispersion

        buffer.put("LOCL".getBytes()); // 参考标识符

        // 设置时间戳（均为目标时间）
        writeTimestamp(buffer, targetTime); // 参考时间戳
        writeTimestamp(buffer, targetTime); // 发起时间戳（从请求复制，这里固定）
        writeTimestamp(buffer, targetTime); // 接收时间戳
        writeTimestamp(buffer, targetTime); // 传输时间戳

        return buffer.array();
    }

    // 写入时间戳（秒数部分+小数部分0）
    private static void writeTimestamp(ByteBuffer buffer, long seconds) {
        buffer.putInt((int) seconds);
        buffer.putInt(0); // 小数部分设为0
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            CustomNTPServer gui = new CustomNTPServer();
            gui.frame.setVisible(true);
        });
    }
}